import React from 'react';
import cls from 'classnames';
import { history } from 'umi';
import _ from 'lodash';
import { connect } from 'dva';
import { Dropdown, Menu } from 'antd';

import { CloseOutlined, DoubleRightOutlined, ReloadOutlined } from '@/utils/antdIcons';
import jurisdiction from '@/utils/jurisdiction';
import sty from './index.less';
import emitter from '#/utils/events';
import renovate from '@/utils/renovate';
import { TRAlert } from '@/components';
import { sendToChildWithAck } from '@/utils/childAppController';

@connect(({ user, global }) => ({
  menuList: user?.menuList || {},
  isLargeScreenIn: global?.isLargeScreenIn || false,
}))
export default class HeaderTabBar extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      unlistenFN: null,
      tabs: [getFirstTab(this.props.menuList)],
      activeKey: '',
      isNextTabByDeleted: false, // delete之后立刻进行的add页面进行排除
    };
    this.scrollContainerRef = React.createRef();
    this.targetEleRefs = [];
  }
  componentDidMount() {
    this.setState({
      unlistenFN: history.listen(this.pathListener.bind(this)),
    });
    emitter.addListener('onChangeMicroApp', (e) => this.microAppChangeListener(e));
  }
  componentWillUnmount() {
    this.state.unlistenFN();
    emitter.removeListener('onChangeMicroApp', this.microAppChangeListener);
    this.setState({
      unlistenFN: null,
    });
  }

  microAppChangeListener(data) {
    this.tabHandles('jumpNewApp', {}, { menus: data.menuList });
  }

  // history监听更新tabs
  pathListener(event) {
    const { pathname, search } = event;
    if (
      this.state.tabs.find((t) => getPurePath(t.path) === getPurePath(pathname))?.key ===
      this.state.activeKey
    ) {
      if (this.state.isNextTabByDeleted) {
        this.setState({
          isNextTabByDeleted: false,
        });
      }
      return;
    }
    let menuItem;
    if (pathname.startsWith('/personal')) {
      menuItem = {
        path: `${pathname}${search ? '?' + search : ''}`,
        name: '个人中心',
        menuCode: pathname.split('/')[1],
      };
    } else {
      menuItem = jurisdiction.getMenuItem(pathname);
    }
    // console.log(menuItem, 'innnnn', search);
    if (!menuItem) return;
    if (this.state.isNextTabByDeleted) {
      this.setState({
        isNextTabByDeleted: false,
      });
    } else {
      const tabItem = {
        path: menuItem.path,
        label: menuItem.name,
        key: menuItem.menuCode,
        menuId: menuItem.menuId,
      };
      const findNavIdx = this.state.tabs.findIndex(({ path }) => {
        return (
          path === pathname || (path.startsWith('/personal') && pathname.startsWith('/personal'))
        );
      });

      if (findNavIdx !== -1) {
        this.tabHandles('add', { key: menuItem.menuCode }, { index: findNavIdx });
      } else {
        this.tabHandles('add', tabItem);
      }
    }
  }

  onDeleteThisTab(e, tab) {
    e && e.stopPropagation();
    this.tabHandles('delete', tab);
  }

  // tabs操作集合
  async tabHandles(type, tab, otherParams = {}) {
    localStorage.setItem('menuId', tab.menuId);
    const { menus = [], index } = otherParams;
    let { key, path } = tab;
    let activeKey = this.state.activeKey;
    let tabs = _.cloneDeep(this.state.tabs);
    let isNextTabByDeleted = this.state.isNextTabByDeleted;

    let renovateRes = { index: 1 };
    if (renovate.isRenovate) {
      renovateRes = await TRAlert.show('当前工作将不被保存，继续执行此操作？');
    }
    if (renovateRes.index !== 1) {
      return;
    }
    if (renovate.isRenovate) {
      await sendToChildWithAck({ type: 'UNLOCK_APP' });
      renovate.isRenovate = false;
    }

    if (type === 'delete') {
      const currentIdx = tabs.findIndex((t) => t.key === key);
      if (activeKey === key) {
        let nextCurrentIdx = currentIdx + 1;
        if (currentIdx === tabs.length - 1) {
          nextCurrentIdx = currentIdx - 1;
        }
        activeKey = tabs[nextCurrentIdx].key;
        path = tabs[nextCurrentIdx].path;
        history.push(path);
      }
      tabs.splice(currentIdx, 1);
      isNextTabByDeleted = true;
    } else if (type === 'add') {
      // console.log(tab, 'tab');
      if (tab.path) {
        tabs = [...tabs, { ...tab, canClose: true }];
      }
      activeKey = key;
      let timer = setTimeout(() => {
        this.scrollToEle(index || -1);
        clearTimeout(timer);
      }, 100);
    } else if (type === 'switchActive') {
      if (activeKey === key) return;
      activeKey = key;
      history.push(path);
      this.scrollToEle(index);
    } else if (type === 'jumpNewApp') {
      const firstTab = getFirstTab(menus);
      activeKey = firstTab.key;
      tabs = [firstTab];
      if (firstTab.path !== history.location.pathname) {
        // 重定向
        history.replace(firstTab.path);
      }
    } else if (type === 'clearAll') {
      const firstTab = tabs[0];
      tabs = [firstTab];
      activeKey = firstTab.key;
      history.push(firstTab.path);
    }

    this.setState({
      activeKey,
      tabs,
      // isNextTabByDeleted,
    });
  }

  handleReload() {
    window.location.reload();
  }

  handleClickDropdownItem({ key }) {
    if (key === 'TAB_GLOBAL_BY_closeAll') {
      if (this.state.tabs.length > 1) {
        this.tabHandles('clearAll', {});
      }
    } else {
      const findCurrentTabIdx = this.state.tabs.findIndex((tab) => tab.key === key);
      this.tabHandles('switchActive', this.state.tabs[findCurrentTabIdx], {
        index: findCurrentTabIdx,
      });
    }
  }

  renderTabsShowMoreDropDownItems() {
    const moreTabs = [
      { label: '关闭全部', key: 'TAB_GLOBAL_BY_closeAll' },
      ...this.state.tabs.slice(1),
    ];

    return (
      <Menu onClick={(e) => this.handleClickDropdownItem(e)}>
        {moreTabs.map((tab) => (
          <Menu.Item key={tab.key}>
            {tab.label}
            {tab.path && (
              <CloseOutlined
                className={sty.closeIcon}
                onClick={(e) => this.onDeleteThisTab(e, tab)}
              />
            )}
          </Menu.Item>
        ))}
      </Menu>
    );
  }

  // -1 滚动到最右侧 -2 无 >=0 滚动到对应下标dom
  scrollToEle = (index = -2) => {
    if (index === -2) return;
    const scrollContainer = this.scrollContainerRef.current;
    if (index === -1) {
      scrollContainer.scrollTo({
        left: scrollContainer.scrollWidth,
        behavior: 'smooth',
      });
    } else {
      const targetElement = this.targetEleRefs[index];

      if (scrollContainer && targetElement) {
        // 获取目标元素相对于滚动容器的左偏移量
        const offsetLeft = targetElement.offsetLeft;
        // 获取滚动容器当前的滚动位置
        const currentScrollLeft = scrollContainer.scrollLeft;
        // 计算需要滚动的距离
        const scrollOffset = offsetLeft - currentScrollLeft;

        scrollContainer.scrollTo({
          left: currentScrollLeft + scrollOffset - 20, // margin-left:20
          behavior: 'smooth',
        });
      }
    }
  };
  render() {
    return (
      <div
        className={cls({
          [sty.headerTabBarBox]: true,
          [sty.headerTabBarBox_largeScreenIn]: this.props.isLargeScreenIn,
        })}
      >
        <div className={sty.tabs} ref={this.scrollContainerRef}>
          <ReloadOutlined className={sty.reload} onClick={() => this.handleReload()} />
          {this.state.tabs.map((tab, index) => (
            <div
              className={cls({
                [sty.activeTab]: this.state.activeKey === tab.key,
                [sty.tabItem]: true,
              })}
              key={tab.key}
              ref={(ref) => (this.targetEleRefs[index] = ref)}
              onClick={() => this.tabHandles('switchActive', tab, { index })}
            >
              {tab.label}
              {tab.canClose && (
                <CloseOutlined
                  className={sty.closeIcon}
                  onClick={(e) => this.onDeleteThisTab(e, tab)}
                />
              )}
            </div>
          ))}
        </div>

        <Dropdown
          overlayClassName={cls({
            [sty.headerTabBarShowMoreDropdownOverlay]: true,
            [sty.headerTabBarShowMoreDropdownOverlay_largeScreenIn]: this.props.isLargeScreenIn,
          })}
          overlay={this.renderTabsShowMoreDropDownItems()}
          trigger={'click'}
        >
          <DoubleRightOutlined className={sty.more} />
        </Dropdown>
      </div>
    );
  }
}

function getFirstTab(menuLs) {
  let deepFn = (ls) => {
    for (const item of ls) {
      if (item.isChildren && item.homePageFlag) {
        return item;
      }
      if (item.children?.length > 0) {
        return deepFn(item.children || []);
      }
    }
  };

  let item = deepFn(menuLs);
  if (!item) {
    item = getFirstMenuItem(menuLs);
  } else {
    item = {
      label: item.name,
      path: item.path,
      key: item.menuCode,
      canClose: false,
      menuId: item.menuId,
    };
  }
  deepFn = null;
  return item;
}

function getFirstMenuItem(menuLs) {
  const firstItem = menuLs[0];
  if (firstItem) {
    if (firstItem.isChildren && firstItem.component) {
      const tabItem = {
        label: firstItem.name,
        path: firstItem.path,
        key: firstItem.menuCode,
        canClose: false,
        menuId: firstItem.menuId,
      };
      return tabItem;
    } else {
      return getFirstMenuItem(firstItem.children);
    }
  } else return {};
}

function getPurePath(path) {
  return path?.split('?')[0];
}
